動態規劃之最長01子序列問題

 問題描述

  • 現在有兩個字符串已知
  • 要求的他們最長的公共子序列長度
  • 例如csdnblog和belong的最長公共子序列是4,由於它們都含有blog這一個子序列

 解題思路與算法思想

既然使用動態規劃算法,那麼算法的核心就是將問題分佈
	這一點和數學歸納法有點相似
假設含有字符串xc長度爲a
有字符串y長度爲b
現在在比較x的前a1位和y的前b1位置的最長公共子序列
	那麼我們需要假設已知之前的所有狀態,如圖:

在這裏插入圖片描述
 程序模型的建立

  • 先將數據輸入
  • 建立轉移方程:
如果當前的兩個字符相同
	那麼加一
如果不同
	在其他狀態之中選擇一個比較大的
  • 之後通過遞歸+記憶的方式計算出匹配的最大字符串
  • 最後將匹配的個數輸出

 數據結構的選用
選用string去儲存這兩個字符串

 程序設計流程
輸入數據
進行計算
輸出結果

 程序設計僞碼算法

	if((c<0)||(d<0))
	{
		return 0 ;
	}
	
	if(bb[c][d]!=-1)
	{
		return bb[c][d] ;
	}
	
	
	if(a[c] == b[d] )
	{
		bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
		return bb[c][d]  ;
	}
	else
	{
		bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
		return bb[c][d]  ;
	
	}

 源程序編碼清單

#include<iostream>
#include<string>
#include<vector>
using namespace std ;
int find_num(string a ,string b ,int c ,int d) ;
vector< vector<int> > bb ;
int main(void)
{
	string a ;
	string b ;
	vector<int>aa ;
	
	
	cin>>a ;
	cin>>b ;
	for(int i = 0 ;i<b.size() ;i++)
	{
		aa.push_back(-1) ;
	}
	for(int i = 0 ;i<a.size() ;i++)
	{
		bb.push_back(aa) ;
	}
	printf("%d",find_num(a,b,a.size()-1,b.size()-1)) ;
}
int find_num(string a ,string b ,int c ,int d) 
{
	if((c<0)||(d<0))
	{
		return 0 ;
	}
	
	if(bb[c][d]!=-1)
	{
		return bb[c][d] ;
	}
	
	
	if(a[c] == b[d] )
	{
		bb[c][d] = find_num(a,b,c-1,d-1)+1 ;
		return bb[c][d]  ;
	}
	else
	{
		bb[c][d] = max(find_num(a,b,c-1,d),find_num(a,b,c,d-1)) ;
		return bb[c][d]  ;
	
	}
}

 程序輸入、輸出

輸入:
csdnblog
belong
輸出:
4

輸入輸出文件,或程序運行結果截圖
在這裏插入圖片描述
 時間與空間複雜度分析
時間複雜度是n^2
 程序使用說明

 總結與完善

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章